package csv

import (
	"fmt"
	"math/rand"
)

var (
	ConfigDropGroupMap        map[int]*DropGroup
	ConfigDropItemGroupMap    map[int]*DropItemGroup
	configStatueMap           map[int]map[int]*configStatue //第一层是ID 第二层是等级
	ConfigRelicsEntryGroupMap map[int]map[int]*ConfigRelicsEntry
	ConfigRelicsLevelMap      map[int]map[int]*ConfigRelicsLevel
	ConfigRelicsSuitMap       map[int][]*ConfigRelicsSuit
	ConfigWeaponLevelMap      map[int]map[int]*WeaponLevel
	ConfigWeaponStarMap       map[int]map[int]*WeaponStar
)

type DropGroup struct {
	DropId      int
	WeightAll   int
	DropConfigs []*ConfigDrop
}
type DropItemGroup struct {
	DropId          int
	DropItemConfigs []*ConfigDropItem
}

func CheckLoadCsv() {
	//二次处理
	MakeDropGroupMap()
	MakeDropItemGroupMap()
	MakeConfigStatueMap()
	MakeConfigRelicsEntryGroupMap()
	MakeConfigRelicsLevelMap()
	MakeConfigRelicsSuitMap()

	MakeConfigWeaponLevelMap()
	MakeWeaponStarMap()
	fmt.Println("csv初始化完成")
}

func MakeConfigStatueMap() {
	configStatueMap = make(map[int]map[int]*configStatue)
	for _, v := range configStatueSlice {
		statueMap, ok := configStatueMap[v.StatueId]
		if !ok {
			statueMap = make(map[int]*configStatue)
			configStatueMap[v.StatueId] = statueMap
		}
		statueMap[v.Level] = v
	}
	return
}

func GetConfigStatue(statueId int, level int) *configStatue {
	_, ok := configStatueMap[statueId]
	if !ok {
		return nil
	}
	_, ok = configStatueMap[statueId][level]
	if !ok {
		return nil
	}

	return configStatueMap[statueId][level]
}

func MakeDropItemGroupMap() {
	ConfigDropItemGroupMap = make(map[int]*DropItemGroup)
	for _, v := range ConfigDropItemSlice {
		dropItemGroup, ok := ConfigDropItemGroupMap[v.DropId]
		if !ok {
			//nil时生成新掉落组
			dropItemGroup = new(DropItemGroup)
			dropItemGroup.DropId = v.DropId
			ConfigDropItemGroupMap[v.DropId] = dropItemGroup
		}
		dropItemGroup.DropItemConfigs = append(dropItemGroup.DropItemConfigs, v)
	}
	//RandDropItemTest()
	//configs := NewGetDropItemGroup(4)
	//fmt.Println(configs)

	return
}

func MakeDropGroupMap() {
	ConfigDropGroupMap = make(map[int]*DropGroup)
	for _, v := range ConfigDropSlice {
		dropGroup, ok := ConfigDropGroupMap[v.DropId]
		if !ok {
			//nil时生成新掉落组
			dropGroup = new(DropGroup)
			dropGroup.DropId = v.DropId
			ConfigDropGroupMap[v.DropId] = dropGroup
		}
		//权重总和 配置
		dropGroup.WeightAll += v.Weight
		dropGroup.DropConfigs = append(dropGroup.DropConfigs, v)
	}
	//RandDropTest()
	return
}

func MakeConfigRelicsEntryGroupMap() {
	//处理 按照Group分类relics

	ConfigRelicsEntryGroupMap = make(map[int]map[int]*ConfigRelicsEntry)
	for _, v := range ConfigRelicsEntryMap {
		relicsGroup, ok := ConfigRelicsEntryGroupMap[v.Group]
		if !ok {
			relicsGroup = make(map[int]*ConfigRelicsEntry)
			ConfigRelicsEntryGroupMap[v.Group] = relicsGroup
		}
		relicsGroup[v.Id] = v
	}
	return
}

func MakeConfigRelicsLevelMap() {
	ConfigRelicsLevelMap = make(map[int]map[int]*ConfigRelicsLevel)
	for _, v := range ConfigRelicsLevelSlice {
		levelMap, ok := ConfigRelicsLevelMap[v.EntryId]
		if !ok {
			levelMap = make(map[int]*ConfigRelicsLevel)
			ConfigRelicsLevelMap[v.EntryId] = levelMap
		}
		levelMap[v.Level] = v
	}
	return
}

func MakeConfigRelicsSuitMap() {
	ConfigRelicsSuitMap = make(map[int][]*ConfigRelicsSuit)
	for _, v := range ConfigRelicsSuitSlice {
		ConfigRelicsSuitMap[v.Type] = append(ConfigRelicsSuitMap[v.Type], v)
	}
	return
}

//key->Weapon Star value->weapon level
//keu->weapon level value->ConfigWeaponLevelSlice

func MakeConfigWeaponLevelMap() {
	ConfigWeaponLevelMap = make(map[int]map[int]*WeaponLevel)
	for _, v := range ConfigWeaponLevelSlice {
		levelMap, ok := ConfigWeaponLevelMap[v.WeaponStar]
		if !ok {
			levelMap = make(map[int]*WeaponLevel)
			ConfigWeaponLevelMap[v.WeaponStar] = levelMap
		}
		levelMap[v.Level] = v
	}
	return
}

//key->Weapon Star value->level
//keu->level value->WeaponStarSlice

func MakeWeaponStarMap() {
	ConfigWeaponStarMap = make(map[int]map[int]*WeaponStar)
	for _, v := range WeaponStarSlice {
		starMap, ok := ConfigWeaponStarMap[v.WeaponStar]
		if !ok {
			starMap = make(map[int]*WeaponStar)
			ConfigWeaponStarMap[v.WeaponStar] = starMap
		}
		starMap[v.Level] = v
	}
	return
}

func RandDropTest() {
	dropGroup := ConfigDropGroupMap[1000]
	if dropGroup == nil {
		return
	}
	num := 0
	for {
		config := NewGetRandDrop(dropGroup)
		if config.IsEnd == LOGIC_TRUE {
			fmt.Println(GetItemName(config.Result))
			num++
			dropGroup = ConfigDropGroupMap[1000]
			if num >= 10 {
				break
			} else {
				continue
			}
		}
		dropGroup = ConfigDropGroupMap[config.Result]
		if dropGroup == nil {
			fmt.Println("表值有误")
			break
		}
	}
}

func RandDropItemTest() {
	//触发事件 获得掉落物
	dropGroup := ConfigDropItemGroupMap[2]
	if dropGroup == nil {
		return
	}
	for _, v := range dropGroup.DropItemConfigs {
		randNum := rand.Intn(PERCENT_ALL)
		if randNum < v.Weight {
			fmt.Println(v.ItemId)
		}
	}
	return
}

func GetRandDrop(dropGroup *DropGroup) *ConfigDrop {
	randNum := rand.Intn(dropGroup.WeightAll)
	randNow := 0
	for _, v := range dropGroup.DropConfigs {
		randNow += v.Weight
		if randNum < randNow {
			return v
		}
	}
	return nil
}

//递归
func NewGetRandDrop(dropGroup *DropGroup) *ConfigDrop {
	randNum := rand.Intn(dropGroup.WeightAll)
	randNow := 0
	for _, v := range dropGroup.DropConfigs {
		randNow += v.Weight
		if randNum < randNow {
			if v.IsEnd == LOGIC_TRUE {
				return v
			}
			dropGroup := ConfigDropGroupMap[v.Result]
			if dropGroup == nil {
				return nil
			}
			return NewGetRandDrop(dropGroup)
		}
	}
	return nil
}

//仓检 只出同一个人
func NewGetRandDrop1(dropGroup *DropGroup, fiveInfo map[int]int, fourInfo map[int]int) *ConfigDrop {

	for _, v := range dropGroup.DropConfigs {
		_, ok := fiveInfo[v.Result]
		if ok {
			index := 0
			maxGetTimes := 0
			for k, config := range dropGroup.DropConfigs {
				_, nowOk := fiveInfo[config.Result]
				if !nowOk {
					continue
				}
				if maxGetTimes < fiveInfo[config.Result] {
					maxGetTimes = fiveInfo[config.Result]
					index = k
				}

			}
			return dropGroup.DropConfigs[index]
		}
		_, ok = fourInfo[v.Result]
		if ok {
			index := 0
			maxGetTimes := 0
			for k, config := range dropGroup.DropConfigs {
				_, nowOk := fourInfo[config.Result]
				if !nowOk {
					continue
				}
				if maxGetTimes < fourInfo[config.Result] {
					maxGetTimes = fourInfo[config.Result]
					index = k
				}

			}
			return dropGroup.DropConfigs[index]
		}
	}

	randNum := rand.Intn(dropGroup.WeightAll)
	randNow := 0
	for _, v := range dropGroup.DropConfigs {
		randNow += v.Weight
		if randNum < randNow {
			if v.IsEnd == LOGIC_TRUE {
				return v
			}
			dropGroup := ConfigDropGroupMap[v.Result]
			if dropGroup == nil {
				return nil
			}
			return NewGetRandDrop1(dropGroup, fiveInfo, fourInfo)
		}
	}
	return nil
}

//仓检 出货平均

func NewGetRandDrop2(dropGroup *DropGroup, fiveInfo map[int]int, fourInfo map[int]int) *ConfigDrop {

	for _, v := range dropGroup.DropConfigs {
		_, ok := fiveInfo[v.Result]
		if ok {
			index := 0
			minGetTimes := 0
			for k, config := range dropGroup.DropConfigs {
				_, nowOk := fiveInfo[config.Result]
				if !nowOk {
					index = k
					break
				}
				if minGetTimes == 0 || minGetTimes > fiveInfo[config.Result] {
					minGetTimes = fiveInfo[config.Result]
					index = k
				}

			}
			return dropGroup.DropConfigs[index]
		}
		_, ok = fourInfo[v.Result]
		if ok {
			index := 0
			minGetTimes := 0
			for k, config := range dropGroup.DropConfigs {
				_, nowOk := fourInfo[config.Result]
				if !nowOk {
					index = k
					break
				}
				if minGetTimes == 0 || minGetTimes > fourInfo[config.Result] {
					minGetTimes = fourInfo[config.Result]
					index = k
				}

			}
			return dropGroup.DropConfigs[index]
		}
	}

	randNum := rand.Intn(dropGroup.WeightAll)
	randNow := 0
	for _, v := range dropGroup.DropConfigs {
		randNow += v.Weight
		if randNum < randNow {
			if v.IsEnd == LOGIC_TRUE {
				return v
			}
			dropGroup := ConfigDropGroupMap[v.Result]
			if dropGroup == nil {
				return nil
			}
			return NewGetRandDrop2(dropGroup, fiveInfo, fourInfo)
		}
	}
	return nil
}

func GetDropItemGroup(dropId int) *DropItemGroup {
	return ConfigDropItemGroupMap[dropId]
}

//多层级调用 递归
func NewGetDropItemGroup(dropId int) []*ConfigDropItem {
	rel := make([]*ConfigDropItem, 0)
	if dropId == 0 {
		return rel
	}
	config := GetDropItemGroup(dropId)
	configAll := make([]*ConfigDropItem, 0)
	for _, v := range config.DropItemConfigs {
		if v.DropType == DROP_ITEM_TYPE_ITEM {
			rel = append(rel, v)
		} else if v.DropType == DROP_ITEM_TYPE_GROUP {
			randNum := rand.Intn(PERCENT_ALL)
			if randNum < v.Weight {
				config := NewGetDropItemGroup(v.ItemId)
				rel = append(rel, config...)
			}
		} else if v.DropType == DROP_ITEM_TYPE_WEIGHT {
			configAll = append(configAll, v)
		}
	}
	if len(configAll) > 0 {
		allRate := 0
		for _, v := range configAll {
			allRate += v.Weight
		}
		randNum := rand.Intn(allRate)
		nowRate := 0
		for _, v := range configAll {
			nowRate += v.Weight
			if nowRate > randNum {
				newConfig := new(ConfigDropItem)
				newConfig.Weight = PERCENT_ALL
				newConfig.DropId = v.DropId
				newConfig.DropType = v.DropType
				newConfig.ItemId = v.ItemId
				newConfig.ItemNumMin = v.ItemNumMin
				newConfig.ItemNumMax = v.ItemNumMax
				newConfig.WorldAdd = v.WorldAdd
				rel = append(rel, newConfig)
				break
			}
		}
	}
	return rel

}

func GetRelicsLevelConfig(mainEntry int, level int) *ConfigRelicsLevel {
	_, ok := ConfigRelicsLevelMap[mainEntry]
	if !ok {
		return nil
	}
	_, ok = ConfigRelicsLevelMap[mainEntry][level]
	if !ok {
		return nil
	}

	return ConfigRelicsLevelMap[mainEntry][level]
}

func GetWeaponLevelConfig(weaponStar int, level int) *WeaponLevel {
	_, ok := ConfigWeaponLevelMap[weaponStar]
	if !ok {
		return nil
	}

	_, ok = ConfigWeaponLevelMap[weaponStar][level]
	if !ok {
		return nil
	}
	return ConfigWeaponLevelMap[weaponStar][level]
}

func GetWeaponStarConfig(weaponStar int, starLevel int) *WeaponStar {
	_, ok := ConfigWeaponStarMap[weaponStar]
	if !ok {
		return nil
	}

	_, ok = ConfigWeaponStarMap[weaponStar][starLevel]
	if !ok {
		return nil
	}
	return ConfigWeaponStarMap[weaponStar][starLevel]
}
